package dal

import (
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"log"
	"os"
	"starry_sky/internal/config"
	"starry_sky/internal/template/sql"
	logger2 "starry_sky/internal/tools/logger"
	"time"
)

var DB *gorm.DB
var SqlTemplate *sql.RootTmpl

// 设置日志等级
func getDbLogLevel() logger.LogLevel {
	switch config.DbConfig.LogLevel {
	case 1:
		return logger.Silent
	case 2:
		return logger.Error
	case 3:
		return logger.Warn
	case 4:
		return logger.Info
	default:
		return logger.Info
	}
}

func Init() {
	nUrl := `host=` + config.DbConfig.Host + ` port=` + config.DbConfig.Port + ` user=` + config.DbConfig.User + ` dbname=` + config.DbConfig.DbName + ` password=` + config.DbConfig.Password + ` sslmode=disable`
	var err error
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			SlowThreshold:             time.Second,     // Slow SQL threshold
			LogLevel:                  getDbLogLevel(), // Log level
			IgnoreRecordNotFoundError: true,            // Ignore ErrRecordNotFound error for logger
			ParameterizedQueries:      false,           // 日志中显示参数
			Colorful:                  true,            // 显示颜色
		},
	)
	for {
		DB, err = gorm.Open(postgres.Open(nUrl), &gorm.Config{
			SkipDefaultTransaction:                   true,
			PrepareStmt:                              true,
			DisableForeignKeyConstraintWhenMigrating: true,
			Logger:                                   newLogger,
		})
		if err != nil {
			logger2.SystemLogger.Error("连接数据库失败！30秒后重连...", err.Error())
			time.Sleep(30 * time.Second)
			db, err := DB.DB()
			if logger2.HasError(err) {
				logger2.SysErrorF("得到数据真是链接错误")
			} else {
				db.Close()
			}
		} else {
			break
		}
	}
	sqlDB, _ := DB.DB()
	// SetMaxIdleConns 设置空闲连接池中的最大连接数
	sqlDB.SetMaxIdleConns(10)
	// SetMaxOpenConns 设置数据库的最大打开连接数。
	sqlDB.SetMaxOpenConns(100)
	// SetConnMaxLifetime 设置可以重用连接的最大时间量。
	sqlDB.SetConnMaxLifetime(time.Hour)
	//初始化表结构 表结构自动迁移
	if config.DbConfig.NeedInit {
		InitTableAndData()
	}
	if config.DbConfig.NeedInitBusiness {
		InitBusinessTableData()
	}
	//初始化模板
	SqlTemplate = sql.New("template/sql")
}
